//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ProvenanceSubscriberMessageParser
{
    using System;
    using Microsoft.Research.ProvenanceSubscriberCommon.Models;
    using Microsoft.Research.eResearch.Blackboard.Common;
    using System.Globalization;

    /// <summary>
    /// This class contains the implementation logic of 
    /// the Processing Status parser logic.
    /// </summary>
    class ProcessingStatusMessageParser : AbstractMessageParser
    {
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="blackBoardMsgParser">BlackboardMessageParser</param>
        public ProcessingStatusMessageParser(BlackboardMessageParser blackBoardMsgParser)
            : base(blackBoardMsgParser)
        { }

        /// <summary>
        /// This function parsers the message for Processing Status details.
        /// </summary>
        /// <param name="message">instance of blackboard message.</param>
        public override void Parse(BlackboardMessage message)
        {
            if (IsActivityEvent(message) || IsWorkflowEvent(message) || IsIterationEvent(message))
            {
                ProvenanceInformationModel provenenceModel = GetProvenanceInfo(message);

                ProcessingStatusModel status = GetProcessStatusInfo(message);
                provenenceModel.ProcessingStatus = status;

                this.BlackboardMessageParser.RaiseProcessingStatusEvent(provenenceModel);
            }
        }

        /// <summary>
        /// Get the Processing Status details.
        /// </summary>
        /// <param name="message">BlackboardMessage</param>
        /// <returns>ProcessingStatusModel</returns>
        private static ProcessingStatusModel GetProcessStatusInfo(BlackboardMessage message)
        {
            ProcessingStatusModel status = new ProcessingStatusModel
            {
                Details = string.Empty,
            };

            DateTime messageTime;
            try
            {
                messageTime = new DateTime(long.Parse(message["time:DateTimeDescription"], CultureInfo.InvariantCulture));
                status.Timestamp = messageTime;
            }
            catch (FormatException)
            {
                //Ignore. 
            }
            catch (ArgumentNullException)
            {
                //Ignore. 
            }
            catch (OverflowException)
            {
                //Ignore. 
            }

            int eventOrder;
            if (!int.TryParse(message["trident:EventOrder"], out eventOrder))
            {
                eventOrder = -1;
            }
            status.EventOrder = eventOrder;

            if (IsActivityEvent(message))
            {
                status.Event = message["trident:ActivityState"];
            }

            if (IsWorkflowEvent(message))
            {
                status.Event = message["trident:WorkflowState"];
                if (message.ContainsKey("trident:ExceptionDetails"))
                {
                    status.Details = message["trident:ExceptionDetails"];
                }
            }

            return status;
        }
    }
}
